package com.bibrApp.difu.api;

import android.content.Context;
import android.os.Environment;


import com.bibrApp.difu.Config;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitNet {
    private static OkHttpClient mOkHttpClient;

    public static int cacheSize = 5 * 1024 * 1024;     // 5 MiB
    public static final String CACHE_PATH
            = Environment.getExternalStorageDirectory().getAbsolutePath()
            + "/okcache";
    public Context mContext;

    private RetrofitNet() {
        initOkHttpClient();
    }

    /**
     * 静态内部类，实例化对象使用
     */
    private static class SingleRetrofitHelper {
        private static final RetrofitNet INSTANCE = new RetrofitNet();
    }

    /**
     * 对外唯一实例的接口
     *
     * @return
     */
    public static RetrofitNet getInstance() {
        return SingleRetrofitHelper.INSTANCE;
    }

    public DfApi getApi() {
        return getApi(false);
    }

    public DfApi getApi(boolean isWalletUrl) {
        Retrofit retrofit;
        if (isWalletUrl) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(Config.WALLET_URL)
                    .client(mOkHttpClient)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        } else {
            retrofit = new Retrofit.Builder()
                    .baseUrl(Config.BASE_URL)
                    .client(mOkHttpClient)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }


        return retrofit.create(DfApi.class);
    }

    /**
     * 初始化OKHttpClient
     */
    private static void initOkHttpClient() {
        /*Cache cache = null;
        if (SDUtils.isSDCardMounted()){
            File cacheDirectory = new File(CACHE_PATH);
            if(!cacheDirectory.exists()){
                try {
                    cacheDirectory.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            cache = new Cache(cacheDirectory, cacheSize);
        }*/
        final X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("SSL");

        sslContext.init(null,new TrustManager[]{trustManager},new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        assert sslContext != null;
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        //日志过滤
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        /*Interceptor networkInter = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                if (!NetWorkUtil.isNetWorkConnected(BiBrApp.getInstance().getAppContext())) {
                    request = request.newBuilder()
                            .cacheControl(CacheControl.FORCE_CACHE)
                            .build();
                }
                Response response = chain.proceed(request);
                *//*if (NetWorkUtil.isNetWorkConnected(BiBrApp.getInstance().getAppContext())) {
                    int maxAge = 0 * 60;
                    // 有网络时 设置缓存超时时间0个小时
                    response.newBuilder()
                            .header("Cache-Control", "public, max-age=" + maxAge)
                        .removeHeader("Pragma")// 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                            .build();
                } else {
                    // 无网络时，设置超时为1天
                    int maxStale = 60 * 60 * 24;
                    response.newBuilder()
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .removeHeader("Pragma")
                            .build();
                }*//*
                return response;
            }
        };*/
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        if (mOkHttpClient == null) {
            synchronized (DfApi.class) {
                if (mOkHttpClient == null) {
                    mOkHttpClient = new OkHttpClient.Builder()
                            .addInterceptor(interceptor)
                            .addInterceptor(new HeaderInterceptor())
                            .hostnameVerifier(new HostnameVerifier() {
                                @Override
                                public boolean verify(String hostname, SSLSession session) {
                                    return true;
                                }
                            })
                            .sslSocketFactory(sslSocketFactory,trustManager)
                            .retryOnConnectionFailure(true)
                            .connectTimeout(5, TimeUnit.SECONDS)
                            .readTimeout(60, TimeUnit.SECONDS)
                            .writeTimeout(60, TimeUnit.SECONDS)
                            .build();
                }
            }
        }
    }

}


